package com.moss.cloud.common.security.config;

import com.moss.cloud.common.core.custom.CustomHttpHeaders;
import com.moss.cloud.common.core.utils.BooleanHandel;
import com.moss.cloud.common.security.condition.CustomCondition;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 自定义Feign请求的客户端认证
 *
 * @author 瑾年
 * @date 2023年11月15日
 */
@Slf4j
@Configuration
@EnableFeignClients
@Conditional(CustomCondition.class)
public class OAuth2ClientAuthenticationConfig {
    @Value("${moss.cloud.clientId}")
    private String clientId;

    @Bean
    public TokenAuthRequestInterceptor tokenAuthRequestInterceptor() {
        return new TokenAuthRequestInterceptor(clientId);
    }


    public static class TokenAuthRequestInterceptor implements RequestInterceptor {
        private final String clientId;

        public TokenAuthRequestInterceptor(String clientId) {
            this.clientId = clientId;
        }

        @Override
        public void apply(RequestTemplate template) {
            log.info("服务间调用透传用户认证:{}", CustomHttpHeaders.FROM_INNER);
            template.header(CustomHttpHeaders.FROM_INNER, clientId);
            BooleanHandel.isTrue(RequestContextHolder.getRequestAttributes() != null).trueHandle(() -> {
                HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
                String token = extractTokenFromRequest(request);
                log.info("用户认证TOKEN:{}", token);
                BooleanHandel.isTrue(StringUtils.isNotBlank(token)).trueHandle(() -> template.header(CustomHttpHeaders.X_CLIENT_TOKEN_USER, token));
            });
        }

        private String extractTokenFromRequest(HttpServletRequest request) {
            return request.getHeader(CustomHttpHeaders.X_CLIENT_TOKEN_USER);
        }
    }

}
